Gatsby 備忘録
#zenn投稿予定
分量が多くなりそうなので、記事に分けるかノートにするかした方が良さそう
gatsby...。使いこなそうと思うと意外と難しい...。
這いずり回り、泥水をすすりながら調べて理解し、大事なポイントだと感じたことを記録しておく。
SSGとは何か
hr.icon
参考記事:SPA, SSR, SSGの違いについて図解でまとめてみた
静的サイトジェネレーターと言う。
このツールは、HTML・CSS・JS・画像などの静的ファイルを事前にビルドで生成してくれる。
従来のWordPressやRailsで作るサイトとは、リクエスト時にDBやAPIからデータを取得する。
対してSSGは、ビルド時にデータを取得すると言う点で、従来のやり方と異なる。
一周回ってWeb黎明期のhtml, cssを作っていた時代に近いとすら思う。手動で作るか自動で作るかの違い。
また、SSGはSPA、SSRとも性質が異なってる。SPAもSSRも結局はリクエスト時にデータを取得してhtmlファイルをレンダリングしてる。SSGはリクエスの前からレンダリングされてる。
SSGの最大のメリットは「応答速度の向上」
リクエストに対して静的ファイルを返すだけなので、圧倒的に応答速度が速い。サイトがサクサク、ヌルヌル動く。
従来のだと、リクエストの中でDBへのアクセスなどを挟むことにより、応答が遅くなる傾向にある。
ただ、SSGの特性上、向くサイト、向かないサイトと言うのはある。
向くサイト
ブログなどの事前にhtmlを作成し切っても問題ないもの。更新頻度が少ないもの。
向かないサイト
twitterやfacebookのように、リアルタイムでデータが更新されるもの。事前にビルドするとかいうのは正直無理。どんだけファイル用意せなあかんねんてなるし。
Gatsbyとは何か
hr.icon
Reactで作られたSSG(静的サイトジェネレーター)
めちゃくちゃシンプルで利用しやすい。世界でもTop3に入る人気を誇ってる。(1位はNext.js)
SSGに特化してて(一応別用途でも利用可だが)、機能が多すぎないのが凄く良い。
ただ、どんなフレームワークでもそうだが、使いこなそうと思うと結構な勉強時間を要することになる。
「Node」こそがGatsbyの中心。Gatsbyで利用したいデータは全て「Node」にしておく。
hr.icon
このNodeはNode.jsのことではないので注意。このNodeは、GraphQLで言及されるノードに近い。
Gatsbyは静的ファイル生成時は、必ずGraphQLを介して必要なデータを取得するのが基本。
CMS、外部API、DB、ファイル、画像などデータソースの種類を問わず、全てGraphQLを通して取得するようにする。
データ取得の一貫性が保たれて、実装が綺麗になる。
極論言ってしまえば、別に外部APIなどはNodeを介する必要も無いが、一貫性を大事にしたいところ。
では、このGraphQLはどこからデータを取得してるのか?CMSや外部APIに直接データを撮りに行ってるのか?
というと違う。ここで登場するのが「Node」。
Gatsbyがあらゆるデータを「Node」というインターフェースに変換してる。
何度も言うが、CMSもDBデータもファイルも全て一度「Node」に変換する。
GraphQLはこの「Node」を参照して(厳密には最初にNodeに合わせたスキーマを生成する必要あり:自動)、Gatsbyの静的ファイル生成時のデータ提供をしている。
以下の画像は公式ドキュメントで出されてる。上記の話を絵で表すとこうなる。
https://scrapbox.io/files/61d31cfa0ffbb8001e351788.png
プラグインでよく見る「Source」と「Transformer」が何かだけでも抑えておくといい
hr.icon
Gatsbyはこっちで特別ゴリゴリコーディングしなくても良いように、便利なプラグインがたくさん用意されてる。
プラグインの中でも大きく2つは抑えておくと良い。
それが「Source系」と「Transformer系」で、こいつらが何をするものなのかを頭に入れておく。
Source系
上の章でも話したように、Gatsbyではまず色んなデータを「Node」に変換できないといけない。
この「Node」に変換される色んなデータのことを「ソース」と呼べばいい。
でSource系のプラグインは、この「ソース」をNodeに変換する役割を持ってる。
例えば、一番よく使うgatbsy-source-filesystemだと、ファイルデータをFile Nodeに変換してくれる。
豆知識:
File Nodeと急に出てきたが、これはgatsby-source-filesystemが勝手に作り出したNodeの型。
このようにNodeには型がある。クラスで言うプロパティ定義的なの。
お察しの通り、Nodeという最低限のインターフェースが用意されており、そのインターフェースを最低限守れてたら、あとはテキトーな型を作ってもいい。
まあ、このNode作成は「Source系」プラグインがやってくれるのであまり気にしなくてもいい。
適したプラグインがなくて、Nodeを自作する必要があるとなった時のために、頭の隅にでも置いておくといい。
Transformer系
こいつは既にあるNodeを、フィルタをかけつつ、より使いやすいNodeに変換する役割を持ってる。
例えばgatsby-transformer-remarkやgatsby-plugin-mdxなどがそう。
gatsby-transformer-remarkは既にあるFile Nodeの中で、拡張子が.mdのものをMarkdownRemark Nodeに変換する。
gatsby-plugin-mdxは既にあるFile Nodeの中で、拡張子が.mdxのものをMdx Nodeに変換する。
このような感じで、既にあるNodeをより使いやすいものに変換するのが「Transformer系」の役割。
Gatsbyの静的ファイルビルドの流れを簡単に把握する
hr.icon
参考:Understanding the lifecycle of Gatsby | Enea Xharja
ちゃんとした詳細は参考ページや公式に譲るとして、ここでは簡単にGatsbyのビルドの流れを把握しておく。
わかりやすさのため、端折ってるフェーズもあるのでご注意を。
また、筆者自身も正確に把握できてないので、これまたご注意を。
ビルドの流れ
1. gatsby-config.jsを読み取って、利用するプラグインを認識する
2. プラグインが、ソースノードと変換ノードを作成する
3. ソースノード及び変換ノードからGraphQL用のスキーマを作成する
4. GraphQLのデータも利用して、静的ページを作成する
5. その他、メタ的なデータの構築を行う
Gatsbyはこのビルドの途中にユーザーがフック関数を挟めるように、gatsby-node.jsやgatsby-browser.jsというものを用意してる。
これらのファイルで、特定のAPIのインターフェースに沿った記述を行うことで、ユーザー独自の処理をビルド内で挟める。
Gatsbyと画像データの関係を把握する
hr.icon
参考:入門者でもわかるGatsbyでの画像の設定方法 | アールエフェクト
Gatsbyで画像データを扱うのは結構ややこしい...
ややこしいポイントは3つ
1. 基本、画像pathをそのまま使えない
2. 最適化をどのタイミングでしてるのかわからない
3. pluginの使い方が主に2つある
1. 基本、画像pathをそのまま使えない
例えば、コンポーネントファイル上で<img src="../sample.png">とか使えない。
Gatsbyは利用する画像ファイルをビルド後のpublic/static配下に任意の名前をつけて配置する。
この配置後のURLをsrc属性に指定してあげないといけない。
実は、配置後のURLはGraphQLから取得できて、publicURLという属性を参照すればいい。
この属性をsrcに与えてあげると、うまく画像が表示される。
2. 最適化をどのタイミングでしてるのかわからない
Gatsbyでは、別に最適化(=画像サイズを小さくする)しなくても画像を利用することは可能。
実際「1.」の<img>タグだけでは最適化できてない。それでも画像を利用できてる。
では、最適化は誰がどのタイミングで行っているのか?
Sharpというものが関わってそうだったら、大体は最適化されてる。
あとgatsby-plugin-imageから利用する<StaticImage>, <GatsbyImage>を利用して画像表示してても最適化されてる。
3. pluginが新しくなって使い方が主に2つある
1. <StaticImage>を使う方法
2. <GatsbyImage>を使う方法
どっちを使ってもいいが、StaticImageの方が使いやすい。
Gatsbyのビルド後のルーティングを決定する方法を把握する
hr.icon
ビルド後のルーティング(ex:/blog, /blog/page/1, /about)の決定方法は主に3つある。
1. src/pages配下に普通に名付けされた.jsファイル(ex:/src/pages/about.js)がそのままルーティングのpathになる。
2. src/pages配下にGraphQLのクエリで名付けされた.jsファイル(ex:src/pages/blog/{mdx.slug}.jsから、対象クエリが存在する値分だけpathになる。
3. gatsby-node.jsで自作したページのpath
src/配下の各ファイル/ディレクトリの役割を把握する
hr.icon
その他
gatsby-plugin-imageがやってること
gatsby-plugin-sharpがやってること
gatsby-remark-...がやってること
gatsby-transform-remarkとgatsby-plugin-mdxの違い
画像をNodeとして使うとはどういうことか?